import { decode, encode } from "cbor-x";


let baseUrl = "http://localhost:3000";
if (import.meta.env.PROD) { // 发布模式
    baseUrl = `${window.location.protocol}://${window.location.host}`;
}

const RESP_HEAD = "resp";
const RESP_OK = "ok";
const RESP_FAIL = "fail";
const RESP_SERIAL_FAIL = "serial_fail";

export interface ErrResp {
    err_code: number,
    err_msg: string,
}

const doHttp = <T, R>(method: 'POST'|'GET', url: string, body: T|null, timeout = 10 * 1000) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, `${baseUrl}${url}`, true);
    xhr.responseType = 'arraybuffer';
    xhr.timeout = timeout;
    if (body != null) {
        xhr.send( encode(body) );
    } else {
        xhr.send();
    }

    return new Promise<R>((resolve, reject) => {
        xhr.onerror = reject;
        xhr.onabort = reject;
        xhr.onload = () => {
            const resp = decode(new Uint8Array(xhr.response as ArrayBuffer));
            const respHead = xhr.getResponseHeader(RESP_HEAD);
            if (respHead != RESP_OK) {
                const err = resp as ErrResp;
                reject(`错误:${err.err_code} ${err.err_msg}`);
                return;
            }
            resolve(resp as R);
        }
    });
}

export const httpGet = async <R>(url: string, timeout = 10 * 1000) => {
    return await doHttp<unknown, R>('GET', url, null, timeout);
}

export const httpPost = async <T, R>(url: string, body: T, timeout = 10 * 1000) => {
    return await doHttp<T, R>('POST', url, body, timeout);
}

export interface User {
    id: number,
    name: string,
    account: string,
    pwd_enc: string,
}

export interface IpInfo {
    status: string,
    country: string,
    countryCode: string,
    region: string,
    regionName: string,
    city: string,
    zip: string,
    lat: number,
    lon: number,
    timezone: string,
    isp: string,
    org: string, 
    as: string,
    query: string,
}

export const getIpInfo = async (ip: string) => {
    return await httpGet<IpInfo>(`/web_api/utils/ip_info?ip=${ip}`);
}


